<?php

/**
 * Class to generate the data to make report from the $startDate,$endDate and $contracts
 */
class EarnedRevenueReportUtil
{

    /**
     * Get contract data within the date ranges, order by state
     * @param string $startDate
     * @param string $endDate
     * @return Array 
     */
    public static function getContractData($startDate, $endDate)
    {
        $contractData = Yii::app()->db->createCommand(
                        <<<HERE
                select c.*,l.state from tbl_contracts c
                    left join tbl_locations l on l.custno = c.custno and l.locno = c.locno
                    where c.contractstartdate between :startDate and :endDate and l.state!=''
                    order by l.state
HERE
                )->bindValues(array(
                    'startDate' => $startDate,
                    'endDate' => $endDate
                ))->queryAll();
        return $contractData;
    }

    /**
     * Generate data for report
     * @param string $startDate
     * @param string $endDate 
     */
    public static function getReportData($startDate, $endDate)
    {
        $contracts = self::getContractData($startDate, $endDate);
        $data = array();
        foreach ($contracts as $contract)
        {
            // contract data it self
            $contractData = array();
            $contractData = $contract;
            $invoiceAndCreditMemoList = self::getInvoiceAndCreditMemoFromContract($contract['contractid'], $startDate, $endDate);
            $contractData['totalInvoiceAndCreditMemo'] = count($invoiceAndCreditMemoList);
            $contractData['items'] = array();
            $contractData['totalAmount'] = 0;
            $contractData['totalTax'] = 0;
            $totalInvoiceAndCreditMemoAmount =0;
            $totalInvoiceAndCreditMemoTax=0;
            // invoice and credit memo data
            foreach ($invoiceAndCreditMemoList as $index => $model)
            {
                /** @var Invoice $model */
                $amount = $model->getAmountChargeIncludeDiscount();
                $tax = $model->getTaxAmount();
                $contractData['items'][$index] = $model->attributes;
                $contractData['items'][$index]['locname'] = $model->location->locname;
                $contractData['items'][$index]['county'] = $model->location->county;
                $contractData['items'][$index]['tax'] = $tax;
                $contractData['totalTax'] += $tax;
                $contractData['totalAmount'] += $amount;
                $totalInvoiceAndCreditMemoAmount += $amount;
                $totalInvoiceAndCreditMemoTax+= $tax;
            }                                           
            $noOfEarnMonth = 0;
            $earn   = self::calculateInvoiceEarnedRevenueAndMonthPass(
                        $contract,
                        $totalInvoiceAndCreditMemoAmount, 
                        $startDate, 
                        $endDate,
                        $noOfEarnMonth); 
            if (is_nan($earn))
            {
                $earn = 0;
            }
            //we use the same function but it's calculating on tax amount
            $earnTax =  self::calculateInvoiceEarnedRevenueAndMonthPass(
                        $contract,
                        $totalInvoiceAndCreditMemoTax, 
                        $startDate, 
                        $endDate);  
            
            $unearn = $totalInvoiceAndCreditMemoAmount - $earn;
            if(is_nan($unearn)) $unearn = 0;
            
            $unearnTax = $totalInvoiceAndCreditMemoTax - $earnTax;
            
            
            //$earn = round($earn, 2);
                      
            $contractData['earn'] = $earn;
            $contractData['earnTax'] = $earnTax;            
            $contractData['unearn'] = $unearn;
            $contractData['unearnTax'] = $unearnTax;
            $contractData['earnMonths'] = $noOfEarnMonth;
            $data[$contract['state']]['contracts'][] = $contractData;
            // for grand summary
            if (!isset($data[$contract['state']]['earn'])) $data[$contract['state']]['earn'] = 0;
            if (!isset($data[$contract['state']]['earnTax'])) $data[$contract['state']]['earnTax'] = 0;
            if (!isset($data[$contract['state']]['unearn'])) $data[$contract['state']]['unearn'] = 0;            
            if (!isset($data[$contract['state']]['unearnTax'])) $data[$contract['state']]['unearnTax'] = 0;
            if (!isset($data[$contract['state']]['totalAmount'])) $data[$contract['state']]['totalAmount'] = 0;            
            if (!isset($data[$contract['state']]['tax'])) $data[$contract['state']]['tax'] = 0;
            
            $data[$contract['state']]['earn'] += $earn;
            $data[$contract['state']]['earnTax'] += $earnTax;
            $data[$contract['state']]['unearn'] += $unearn;
            $data[$contract['state']]['unearnTax'] += $unearnTax;
            $data[$contract['state']]['totalAmount'] +=$contractData['totalAmount'];
            $data[$contract['state']]['tax'] +=$contractData['totalTax'];
        }
     
        return $data;
    }

    /**
     * Find all invoice and contract belong to that contract   
     * @param Contracts $contract
     * @return type 
     */
    protected static function getInvoiceAndCreditMemoFromContract($contractid, $startDate, $endDate)
    {
        $modelList = Invoice::model()->findAll(
                '(invoicedate between :startDate and :endDate) and
                    (invoicetype=:invoice or invoicetype=:creditmemo) and agreementno=:agreementno', array(
            'startDate' => $startDate,
            'endDate' => $endDate,
            'agreementno' => $contractid,
            'invoice' => Invoice::TYPE_INVOICE,
            'creditmemo' => Invoice::TYPE_CREDIT_MEMO
                )
        );
        return $modelList;
    }

    protected static function calculateInvoiceEarnedRevenueAndMonthPass(
        $contract, 
        $totalInvoiceAndCreditMemoAmount, 
        $startDate, 
        $endDate,
        &$monthPass = 0
    )
    {
        $startDate = new DateTime($contract['contractstartdate']);
        $endDate = new DateTime($endDate);
        $endContractDate = new DateTime($contract['contractenddate']);
        $endContractDate->add(new DateInterval('P1D'));

        if($endDate > $endContractDate){
            $endDate = $endContractDate;
        }
//        if (strtotime($endDate) < strtotime($contract['contractenddate']))
//        {
//            $endDate = new DateTime($endDate);
//        }
//        el
//        {
//            $endDate = new DateTime($contract['contractenddate']);
//        }

        $contractAmount = $contract['contractamount'];
        $startMonth = $startDate->format('m');
        if ($contract['contractype'] == Contracts::TYPE_MONTHLY || $contract['contractype'] == Contracts::TYPE_QUARTERLY)
        {
            $contractMonthDiff = $startDate->diff($endContractDate, true);
            $monthPassDiff = $endDate->diff($startDate);
            $contractMonth = $contractMonthDiff->format('%y') * 12 + $contractMonthDiff->format('%m');
            $monthPass = $monthPassDiff->format('%y') * 12 + $monthPassDiff->format('%m');
        }
        else
        {
            $contractMonth = 12;
            $monthPassDiff = $endDate->diff($startDate);
            $monthPass = $monthPassDiff->format('%y') * 12 + $monthPassDiff->format('%m');
        }

        $earn = 0;
       
        if ($monthPass > 0 && $contractAmount>0)
        {
            $earn = $totalInvoiceAndCreditMemoAmount / $contractMonth * $monthPass;
        }
        else
        {
            $earn = 0;
        }
       
        if(is_nan($earn)) $earn = 0;
        return $earn;
    }

    protected static function getRevenueByMonth($amountPerMonth, $startMonth, $monthPass, $contractMonth)
    {
        $rs = array();
        //$startMonth++;
        for ($i = 1; $i <= 24; $i++)
        {
            if ($i >= $startMonth && $i < $startMonth + $monthPass && $i < $contractMonth + $startMonth)
            {
                $rs[$i] = $amountPerMonth;
            }
            else
            {
                $rs[$i] = 0;
            }
        }
        return $rs;
    }

    protected static function getViewName()
    {
        return '/pdf/newEarnRevenueReportForm';
    }

}

?>
